*** Sexism and Voting for Women Candidates - BJPS replication do-files
*** Canada

log using "C:\Users\a15014rs\Dropbox\Sexism and Candidates\Analysis\BJPS replication files\Canada_log_file.log", replace

** Recode 2015 results to calculate distance from winner in previous election

cd "C:\Users\a15014rs\Dropbox\Sexism and Candidates\Data\Canada\"

** get winners share 2015 - from Elections Canada
import delimited "table_tableau12.csv", clear

drop if majoritymajoritã==.
keep electoraldistrictnum* percentageofvotesobtainedpourcen

rename electoraldistrictnum* districtnumber
rename percentageofvotesobtainedpourcen winner_share

save "Canada_2015_winner_share.dta", replace

** get distance and non-winning party results
import delimited "Canada_JohnsonEtAl.csv", clear

drop if v1!=2015

rename v3 districtnumber
rename v4 ndistrictname
rename v10 party
rename v13 distance

keep ndistrictname districtnumber party distance
replace distance=0 if distance<0.000001

merge m:1 districtnumber using "Canada_2015_winner_share.dta"
drop _merge

gen distance2 = distance*100
drop distance 
rename distance2 distance

gen share=winner_share-distance

saveold "Canada_constituency_data_2015_for_merge.dta", replace

*************************************************************************************************************

** Recode 2019 results - district level for candidate characteristics and CES for individual-level

import delimited "Canada_JohnsonEtAl.csv", clear

keep if v1==2019
drop v1

rename v2 prov
rename v3 ndistrict
rename v4 ndistrictname
rename v5 incumbent
rename v6 gender
rename v10 party
rename v12 winner

* Renaming variables and adding labels for clarity 
label define prov_label 10 "Newfoundland and Labrador" 11 "PEI" 12 "Nova Scotia" 13 "New Brunswick" 24 "Quebec" 35 "Ontario" 46 "Manitoba" 47 "Saskatchewan" 48 "Alberta" 59 "British Columbia" 60 "Yukon" 61 "Northwest Territories" 62 "Nunavut"

label values prov prov_label

* descriptives: female candidates
tab gender
tab party gender, row 
tab incumbent gender, row
tab winner gender, row 

encode gender, gen(gender2)
drop gender
rename gender2 gender

* create a fake districtnumber variable to check the joining
gen ndistrict_temp = ndistrict
	 
sort ndistrict

saveold "canada_candidates_edited.dta", replace

/** measure of distance from winner in the previous election - 2015 **/
rename ndistrict districtnumber
merge 1:1 districtnumber party using "Canada_constituency_data_2015_for_merge.dta"

/** distance = median if party ran in 2019 but not in 2015 **/
tabstat distance if winner_share!=0, stats(median)
replace distance = 13.6 if distance==.
gen distance2 = distance/100
drop distance
rename distance2 distance

/*share = 0 if did not stand at previous election*/
replace share=0 if share==.

drop _merge

saveold "canada_candidates_edited.dta", replace

* Merge the candidate and voter data 

use "2019CES-online.dta", clear 
rename constituencynumber districtnumber

gen id=_n

sort districtnumber

joinby districtnumber using "canada_candidates_edited.dta"

** drop respondents only in the pre-election wave
drop if pes19_panel==""

save "Canada_data.dta", replace

********************************************************************************************************************

** Analysis

use "Canada_data.dta", clear

* Create variable for women races
drop if gender==3
fre gender
egen women_race = min(gender), by(ndistrictname)
egen women_only = max(gender), by(ndistrictname)
gen sample_races=1 if women_race==1&women_only==2
replace sample_races=0 if sample_races==.

codebook ndistrictname if sample_races==1
**all-women races
codebook ndistrictname if women_race==2
**all-male races
codebook ndistrictname if women_only==1

** Sexism measures
gen appreciate = pes19_hostile1
gen control = pes19_hostile2
gen innocent = pes19_benevolent3
gen cherished = pes19_benevolent1
gen purity = pes19_benevolent2
gen pedestal = pes19_benevolent3

* remove the DK 
foreach x in appreciate control innocent cherished purity pedestal {
recode `x' 6 = .
}

* scale to range - 2 to +2 (positive values = high in sexism)
recode appreciate 1=-2 2=-1 3=0 4=1 5=2
recode control   1=-2 2=-1 3=0 4=1 5=2
recode innocent   1=-2 2=-1 3=0 4=1 5=2
recode cherished   1=-2 2=-1 3=0 4=1 5=2
recode purity   1=-2 2=-1 3=0 4=1 5=2
recode pedestal   1=-2 2=-1 3=0 4=1 5=2

* Create scales
* rowtotal 
egen hostile = rowtotal(innocent control appreciate), missing
egen benevolent = rowtotal(cherished purity pedestal), missing
pwcorr hostile benevolent

* Recode -1 to +1 
gen hostile_rescale = hostile / 6
gen benevolent_rescale = benevolent/ 6

gen hostile_rescale2 = hostile_rescale+1
gen benevolent_rescale2 = benevolent_rescale+1

** respondents missing on sexism items
codebook id if hostile_rescale2!=.
codebook id if pes19_hostile1!=.

gen nothostile=1 if hostile_rescale<0
replace nothostile=0 if hostile_rescale>=0
gen hostile2=1 if hostile_rescale>0
replace hostile2=0 if hostile_rescale<=0


** Restrict sample to voters
gen voted=1 if pes19_turnout2019==1|pes19_turnout2019_v2==1
replace voted=0 if pes19_turnout2019==2| ///
	pes19_turnout2019==5|pes19_turnout2019==6|pes19_turnout2019_v2==2
*keep if pes19_turnout2019==1|pes19_turnout2019_v2==1

** Party identifier indicator
gen nonpartisan=1 if pes19_pid_close==2|pes19_pidtrad==8
replace nonpartisan=0 if nonpartisan!=1
replace nonpartisan=. if pes19_pid_close==3|pes19_pidtrad==9

** Party
gen party_candidate=1 if party=="Liberal"
replace party_candidate=2 if party=="Conservative"
replace party_candidate=3 if party=="NDP"
replace party_candidate=4 if party=="Bloc"
replace party_candidate=5 if party=="Green"
label define partylab 1 "Liberal" 2 "Conservative" 3 "NDP" 4 "Bloc" 5 "Green"
label values party_candidate partylab

** respondent gender
gen female=1 if cps19_gender==2
replace female=0 if cps19_gender==1
label define femlab 0 "men" 1 "women"
label values female femlab

** Binary sexism variable
gen hostile_sexist_binary=1 if hostile_rescale>0&hostile_rescale!=.
replace hostile_sexist_binary=0 if hostile_rescale<=0

** Reverse code candidate gender
gen gender2=1 if gender==1
replace gender2=0 if gender==2
replace gender2=. if gender==3
drop gender
rename gender2 gender
label define genderlab 0 "male candidate" 1 "female candidate"
label values gender genderlab

** Generate numerical variables
encode incumbent, gen(incumbent2)
codebook incumbent2
drop incumbent
rename incumbent2 incumbent

** Vote choice (excludes non-voters)
gen vote_choice = 1 if pes19_votechoice2019==1&party=="Liberal"
replace vote_choice = 1 if pes19_votechoice2019==2&party=="Conservative"| ///
	pes19_votechoice2019==3&party=="NDP"| ///
	pes19_votechoice2019==4&party=="Bloc"| ///
	pes19_votechoice2019==5&party=="Green"
replace vote_choice=0 if vote_choice==.
replace vote_choice=. if pes19_votechoice2019==8|pes19_votechoice2019==9|pes19_turnout2019>=2&pes19_turnout2019<=8| ///
	pes19_turnout2019_v2>=2&pes19_turnout2019_v2<=4

gen fullsample=1 if vote_choice!=.&gender!=.&hostile_rescale!=.&female!=.&party_candidate!=.&incumbent!=.&distance!=.&hostile_rescale!=.& ///
	sample_races==1
replace fullsample=0 if fullsample!=1

codebook pes19_ResponseId if pes19_votechoice2019!=.&hostile_rescale2!=.&sample_races==1&gender!=.&female!=.&party_candidate!=.&incumbent!=.& ///
	distance!=.&vote_choice!=.


save "Canada_data_recoded.dta", replace

** identify respondents with all zeros on vote choice dependent var
clogit vote_choice i.gender [pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
gen wanted=e(sample)
tab wanted

** Keep analytical sample
keep if wanted==1

** sample size
codebook pes19_ResponseId

** scale reliability for analytical sample
alpha appreciate control innocent

** graph scheme
set scheme cleanplots

** Models
** Voting for female candidates - with and without controls
* note - set the baseline for party at conservative to align with US and UK for tables 

cd "C:\Users\a15014rs\Dropbox\Sexism and Candidates\"

set more off
quietly clogit vote_choice i.gender [pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Canada.doc", replace se or
margins, dydx(gender) post
est store model_1
clogit vote_choice i.gender ib2.party_candidate i.incumbent c.distance [pw=pes19_weight_general_all] ///
	if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Canada.doc", merge se or
margins, dydx(gender) post
est store model_2
coefplot (model_1, label("M1 - Without controls")) (model_2, label("M2 - With controls")), title("Canada") ///
	ytitle("AME voting for female candidate") ylabel("") xline(0) saving("Output\BJPS resubmission\Canada_table6", replace)


** Voting for female candidates by hostile sexism (controlling for sexism*party)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 7 Canada.doc", replace se or ctitles("", " c. gender*sexism") starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 7 Canada.doc", merge se or ctitles("", " c. gender*sexism") starlevels(10 5 1)

** Robustness checks
* men and women
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&female==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\gender Canada.doc", replace se or ctitles("", " c. gender*sexism") starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&female==0, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\gender Canada.doc", merge se or ctitles("", " c. gender*sexism") starlevels(10 5 1)

* for partisans and non partisans 
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&nonpartisan==0, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\partisanship Canada.doc", replace se or ctitles("", "partisans") starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&nonpartisan==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\partisanship Canada.doc", merge se or ctitles("", "non partisans") starlevels(10 5 1)

* By party
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&pes19_pid==1| ///
	fullsample==1&sample_races==1&pes19_pidtrad==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\party Canada.doc", replace se or ctitles("", " c. Liberal identifiers") starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&pes19_pid==2| ///
	fullsample==1&sample_races==1&pes19_pidtrad==2, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\party Canada.doc", merge se or ctitles("", " c. Conservative identifiers") starlevels(10 5 1)

* Using "women seek to gain power by getting control over men" (consistent across countries)
clogit vote_choice i.gender##c.control ib2.party_candidate##c.control i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\control item Canada.doc", replace se or ctitles("", " c. gender*sexism") starlevels(10 5 1)

* Benevolent sexism
clogit vote_choice i.gender##c.benevolent_rescale2 ib2.party_candidate##c.benevolent_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\benevolent Canada.doc", replace se or ctitles("", " c. gender*sexism") starlevels(10 5 1)

* Vote share at previous election control
pwcorr distance share
** correlation = -0.5369
clogit vote_choice i.gender ib2.party_candidate i.incumbent c.share [pw=pes19_weight_general_all] ///
	if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\vote share control Canada.doc", replace se or
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate i.incumbent c.share ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\vote share control Canada.doc", merge se or ctitles("", " c. gender*sexism") starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.share ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Robustness checks\vote share control Canada.doc", merge se or ctitles("", " c. gender*sexism") starlevels(10 5 1)


** Revisions #2 - Quebec only
set more off
clogit vote_choice i.gender [pw=pes19_weight_general_all] if fullsample==1&sample_races==1&prov==24, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Quebec.doc", replace se or
clogit vote_choice i.gender ib2.party_candidate i.incumbent c.distance [pw=pes19_weight_general_all] ///
	if fullsample==1&sample_races==1&prov==24, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Quebec.doc", merge se or
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&prov==24, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Quebec.doc", merge se or starlevels(10 5 1)
clogit vote_choice i.gender##c.hostile_rescale2 ib2.party_candidate##c.hostile_rescale2 i.incumbent c.distance ///
	[pw=pes19_weight_general_all] if fullsample==1&sample_races==1&prov==24, group(pes19_ResponseId) or
outreg using "Output\BJPS resubmission\Table 6 Quebec.doc", merge se or starlevels(10 5 1)

** Table 3 for analytical sample only
collapse hostile2 nothostile [iw=pes19_weight_general_all], by(pes19_ResponseId)

tab nothostile
tab hostile2


use "Data\Canada_data_recoded.dta", clear

** Abstention models
** Individual-level covariates
gen educ=1 if cps19_education>=1&cps19_education<=4
replace educ=2 if cps19_education==5
replace educ=3 if cps19_education>=6&cps19_education<=7
replace educ=4 if cps19_education>=8&cps19_education<=11

label define educlab 1 "Lower than Secondary" 2 "Secondary" 3 "Techical" 4 "University"
label values educ educlab

gen workstat=1 if cps19_employment==1|cps19_employment==3
replace workstat=2 if cps19_employment==2
replace workstat=3 if cps19_employment==4|cps19_employment==11
replace workstat=4 if cps19_employment==5
replace workstat=5 if cps19_employment==6|cps19_employment==9
replace workstat=6 if cps19_employment==7|cps19_employment==10
replace workstat=7 if cps19_employment==8
replace workstat=8 if cps19_employment==12

label define worklab 1 "Employed FT" 2 "Employed PT" 3 "Retired" 4 "Unemployed" ///
	5 "Student" 6 "Caring for a family" 7 "Disabled" 8 "Other"
label values workstat worklab

* Abstainers
gen abstain=1 if voted==0
replace abstain=0 if voted==1


gen employment = . 
replace employment = 1 if cps19_employment == 1 | cps19_employment == 2 | cps19_employment == 3 | cps19_employment == 9 | cps19_employment == 10 | cps19_employment == 11 
replace employment = 0 if cps19_employment == 5 | cps19_employment == 7 | cps19_employment == 8
replace employment = 2 if cps19_employment == 4
replace employment = 3 if cps19_employment == 6 

label define employment_label 1 "In paid work" 0 "Out of paid work" 2 "Retired" 3 "Student"
label values employment employment_label

gen union = cps19_union
recode union 3=. 
recode union 2=0 1=1 

gen income = cps19_income_cat
recode income 1=2

* Co-partisan
gen copartisan=1 if party=="Liberal"&pes19_pid==1| ///
	party=="Conservative"&pes19_pid==2| ///
	party=="NDP"&pes19_pid==3| ///
	party=="Bloc"&pes19_pid==4| ///
	party=="Green"&pes19_pid==7| ///
	party=="Liberal"&pes19_pidtrad==1| ///
	party=="Conservative"&pes19_pidtrad==2| ///
	party=="NDP"&pes19_pidtrad==3| ///
	party=="Bloc"&pes19_pidtrad==4| ///
	party=="Green"&pes19_pidtrad==5	
replace copartisan=0 if copartisan==.

drop if copartisan==0

codebook pes19_ResponseId if abstain!=.&hostile_rescale!=.&gender!=.&female!=.&educ!=.&pes19_age!=.&employment!=.&union!=.& ///
	prov!=.&distance!=.&income!=.

** Turnout Models 

logit abstain c.hostile_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1 & copartisan == 1, or
outreg using "Output\BJPS resubmission\Table 8 Canada.doc", replace se or ctitles("", "Abstention") starlevels (10 5 1)
margins gender, at(hostile_rescale2=(0(1)2))
marginsplot, ytitle("Probability of abstaining") xtitle("") xlabel(0 "Not sexist (<1)" 1 "Neutral (1)" 2 "Sexist (>1)") ///
	title("Canada") saving("Output\BJPS resubmission\Canada_table8", replace)

** Robustness - restrict sample to non-missing on income
logit abstain c.hostile_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1 & copartisan == 1 & income!=., or

** Robustness - by party
logit abstain c.hostile_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1&pes19_pid==1|sample_races==1&pes19_pidtrad==1, or
outreg using "Output\BJPS resubmission\Robustness checks\party turnout Canada.doc", replace se or ctitles("" "c. Liberal identifiers") starlevels (10 5 1)
logit abstain c.hostile_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1&pes19_pid==2|sample_races==1&pes19_pidtrad==2, or
outreg using "Output\BJPS resubmission\Robustness checks\party turnout Canada.doc", merge se or ctitles("" "c. Conservative identifiers") starlevels (10 5 1)

** Robustness - using "women seek to gain power by getting control over men"
logit abstain c.control##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1 & copartisan == 1, or
outreg using "Output\BJPS resubmission\Robustness checks\control turnout Canada.doc", replace se or ctitles("", "Abstention") starlevels (10 5 1)

** Robustness - benevolent sexism
logit abstain c.benevolent_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.distance i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1 & copartisan == 1, or
outreg using "Output\BJPS resubmission\Robustness checks\benevolent turnout Canada.doc", replace se or ctitles("", "Abstention") starlevels (10 5 1)

** Vote share control
logit abstain c.hostile_rescale2##i.gender i.female i.educ c.pes19_age i.employment c.share i.incumbent ///
	i.union i.prov [pw=pes19_weight_general_all] if sample_races==1 & copartisan == 1, or
outreg using "Output\BJPS resubmission\Robustness checks\vote share control turnout Canada.doc", replace se or ctitles("", "Abstention") starlevels (10 5 1)


use "Data\Canada_data_recoded.dta", clear 

** 80% turnout in the weighted sample
** Abstainers
gen abstain=1 if voted==0
replace abstain=0 if voted==1


** Abstainers versus voters on sexism
collapse abstain hostile_rescale [iw=pes19_weight_general_all], by(pes19_ResponseId)
drop if hostile_rescale==.

gen nothostile=1 if hostile_rescale<0
replace nothostile=0 if hostile_rescale>=0
gen hostile2=1 if hostile_rescale>0
replace hostile2=0 if hostile_rescale<=0

tab abstain hostile2, row
tab abstain nothostile, row

log close















